﻿using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Algorithms
{
    /// <summary>
    /// https://leetcode.com/problems/print-zero-even-odd/
    /// </summary>
    public class ZeroEvenOdd
    {
        private int n;
        private volatile int c = 0;
        AutoResetEvent z = new AutoResetEvent(true);
        AutoResetEvent e = new AutoResetEvent(false);
        AutoResetEvent o = new AutoResetEvent(false);

        public ZeroEvenOdd(int n)
        {
            this.n = n;
        }
        public void Zero(Action<int> printNumber)
        {
            while (true)
            {
               
                z.WaitOne();
                if (c < n)
                {
                    printNumber(0);
                    c++;
                    if (c % 2 == 1)
                    {
                        o.Set();
                    }
                    else
                    {
                        e.Set();
                    }
                }
                else
                {
                    c++;
                    o.Set();
                    e.Set();
                    break;
                }

            }
            //z.Dispose ();
            //Console.WriteLine("exit:z");
        }

        public void Even(Action<int> printNumber)
        {

            while (c <= n)
            {
                e.WaitOne();
                if (c <= n)
                {
                    printNumber(c);
                }
                z.Set();
                if (c > n)
                {
                    break;
                }
            }
           // Console.WriteLine("exit:e");
        }

        public void Odd(Action<int> printNumber)
        {
            while (c <= n)
            {
                o.WaitOne();
                if (c <= n)
                {
                    printNumber(c);
                }
                z.Set();
                if (c > n)
                {
                    break;
                }
            }
          //  Console.WriteLine("exit:o");
        }
    }


}
